﻿using System;
using System.Reflection;
using System.Linq;

namespace Axial
{
	public static partial class CallHandler
	{
		[CallHandler(typeof(string))]
		private static string HandleString(MethodInfo method, object called, object[] stack)
		{
			if (method.Name == "Concat")
				if (stack.Length == 1)
					return stack[0] + ".join('')";
				else
					return string.Join(" + ", (from i in Enumerable.Range(0, stack.Length)
											   select "(" + stack[i] + ")").ToArray());
			if (method.Name == "Replace")
				return string.Format("{0}.replace(/{1}/g, {2})", called, stack[0].ToString().RemoveOuterCharacters(), stack[1]);
			if (method.Name == "get_Length")
				return string.Format("{0}.length", called);
			if (method.Name == "op_Inequality")
				return string.Format("{0} != {1}", stack[0], stack[1]);
			if (method.Name == "op_Equality")
				return string.Format("{0} == {1}", stack[0], stack[1]);
			if (method.Name == "ToLower")
				return called + ".toLowerCase()";
			return null;
		}

		[CallHandler(typeof(int))]
		private static string HandleInt32(MethodInfo method, object called, object[] stack)
		{
			if (method.Name == "Parse")
				return string.Format("parseInt({0})", stack[0]);
			return null;
		}

		[CallHandler(typeof(object))]
		private static string HandleObject(MethodInfo method, object called, object[] stack)
		{
			if (method.Name == "ToString")
				return string.Format("String({0})", called);
			return null;
		}

		[CallHandler(typeof(System.Drawing.Point))]
		private static string HandlePoint(MethodInfo method, object called, object[] stack)
		{
			return StandardHandler(method, called, stack);
		}

		[CallHandler(typeof(Nullable<>))]
		private static string HandleNullable(MethodInfo method, object called, object[] stack)
		{
			if (method.Name == "GetValueOrDefault" || method.Name == "get_Value")
				return called.ToString();
			if (method.Name == "get_HasValue")
				return "(" + called + " != null)";
			return null;
		}
	}
}
